// Application.cpp

#include "stdafx.h"
#include "MessageSystem.h"
#include "RenderSystem.h"
#include "SceneManager.h"
#include "InputManager.h"
#include "Skydome.h"
#include "Heightmap.h"
#include "CameraControl.h"
#include "Application.h"

#include "RenderObject.h"

#include "EntityManager.h"
#include "EntityFactory.h"
#include "BasicTower.h"

#include "ResourceManager.h"

#include "GameState.h"
#include "MenuState.h"
#include "StateManager.h"
#include "AudioSystem.h"
#include "GraphicalUserInterface.h"
#include "ParticleRenderer.h"

using namespace DirectX;

Application::Application() : m_systems(nullptr), m_state_manager(nullptr) {}
Application::~Application() {};

bool Application::Init(MessageSystem *message_system, InputManager* input_manager,HWND window_handle,ConfigFile &cfg) {
	float width=cfg.HasKey("width")?cfg.AsFloat("width"):1280;
	float height=cfg.HasKey("height")?cfg.AsFloat("height"):720;

	m_systems = new Systems;
	m_systems->m_config_file = &cfg;
	m_systems->m_message_system = message_system;

	m_systems->m_render_system = new RenderSystem;
	if(!m_systems->m_render_system->Init((int)width,(int)height,window_handle)) {
		System::Notify("Could not initialize RenderSystem!\n"\
			"Read log.txt for more information.","Error!");
		return false;
	};

	m_systems->m_input_manager = input_manager;
	m_systems->m_scene_manager=new SceneManager();
	m_systems->m_scene_manager->Init();
	m_systems->m_resource_manager = new ResourceManager(m_systems->m_render_system);

	m_systems->m_gui_manager = new GuiManager(m_systems->m_render_system, m_systems->m_message_system, m_systems->m_resource_manager);
	m_systems->m_gui_manager->Init((int)width, (int)height);
	m_systems->m_audio_system = new AudioSystem;
	if (!m_systems->m_audio_system->Init()){
		return false;
	}
	IAudio::SetAudioSystem(m_systems->m_audio_system);

	m_state_manager = new StateManager(m_systems);
	if (!m_state_manager->Init()){
		return false;
	}
	State::Create<GameState>(m_state_manager, "GameState");
	State::Create<MenuState>(m_state_manager, "MenuState");

	m_camera.SetPerspective(width/height,DirectX::XM_PIDIV4,m_systems->m_config_file->AsFloat("c_znear"),m_systems->m_config_file->AsFloat("c_zfar"));
	m_systems->m_camera = &m_camera;
	
	m_state_manager->ChangeState(m_state_manager->FindById("MenuState"));
	return true;
};

void Application::Shut() {
	if (m_state_manager){
		 delete m_state_manager;
		 m_state_manager = nullptr;
	}
	if(m_systems->m_scene_manager) {
		m_systems->m_scene_manager->Shut();
		delete m_systems->m_scene_manager;
		m_systems->m_scene_manager=nullptr;
	}
	if(m_systems->m_render_system) {
		m_systems->m_render_system->Shut();
		delete m_systems->m_render_system;
		m_systems->m_render_system=nullptr;
	}
	if (m_systems->m_gui_manager){
		m_systems->m_gui_manager->Shut();
		delete m_systems->m_gui_manager;
		m_systems->m_gui_manager = nullptr;
	}
	if (m_systems->m_resource_manager){
		delete m_systems->m_resource_manager;
		m_systems->m_resource_manager = nullptr;
	}
	if (m_systems->m_audio_system){
		m_systems->m_audio_system->Shut();
		delete m_systems->m_audio_system;
		m_systems->m_audio_system = nullptr;
	}
	if (m_systems){
		delete m_systems;
		m_systems = nullptr;
	}
};

void Application::Tick() {
	m_timer.Update();
	if (m_timer.GetDelta() > 0.1f) //Fulhack
		m_timer.SetDelta(0.0f);
	m_state_manager->Update(m_timer.GetDelta());
	m_systems->m_audio_system->Update();
	m_state_manager->Render();
};

// protected:

